import random
import re
import string
import jwt
import redis
import time
from django.contrib.auth.hashers import check_password
from django.db.models import Q
from django.http.response import HttpResponse
from captcha.image import ImageCaptcha
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
from shop import settings
from users.models import Users,Addr


# 用户名
class CheckUserName(APIView):
    """
        校验用户名
        # 如何选择继承的视图类
            # 根据业务逻辑分析
        # 业务逻辑分析
        1. 获取前端传来用户名
        2. 判断用户名是否存在
          1. 存在,说明用户名已经使用,应该抛出错误
          2.不存在, 正常返回
        """
    def get(self,request,name):
        # 获取前端传来用户名
        if not name:
            # 没有获取到前端传来的用户名
            return Response({'msg':'用户名获取失败','code':400})
        # 用户名存在
        # 判断用户名在数据库中是否存在
        try:
            user = Users.objects.get(username=name)
            # 此时获取到用户, 说明此用户名已经存在,抛出错误
            return Response({'msg':'用户名已经存在','code':400})
        except Exception as e:
            # 此时说明用户名不存在, 正常返回
            return Response({'msg':'ok','code':200})

# 电话号码
class CheckMobile(APIView):
    def get(self,rquest,mobile):
        """校验手机号是否重复"""
        if not mobile:
            Response({'msg':'手机号获取失败','code':400})
        try:
            user = Users.objects.get(mobile=mobile)
            # 此时获取到用户, 说明此手机号已经存在,抛出错误
            return Response({'msg':'手机号已经存在','code':200})
        except:
            # 说明手机号不存在
            return Response({'msg':'ok','code':200})

# 生成图片验证码
class GenerateImageCode(APIView):
    def get(self, request, img_id):
        # 使用随机模块生成: 字符+数字的随机数,长度6
        # 生成的是数字+字符的字符串: eg: asWE23  we34WE
        # string.ascii_letters  生成区分大小写的字符
        # string.digits: 生成0-9de 随机数字
        code = ''.join(random.sample(string.ascii_letters + string.digits, 4))
        # 生成一张图片
        # 把生成的随机数字添加图片上
        img = ImageCaptcha()
        image = img.generate(code)
        # 把生成的图片上的数字写入redis,便于后期校验
        # redis链接
        redis_cli = redis.Redis(host='localhost',port=6379)
        redis_cli.setex('img_%s'%img_id,60,code)
        redis_cli.close()
        # 返回图片
        return HttpResponse(image, content_type="image/jpg")

# 校验图片验证码
class CheckImageCode(APIView):
    def get(self,request):
        uuid = request.query_params.get('imageCodeID')
        code = request.query_params.get('imageCode')
        redis_cli = redis.Redis(host='localhost',port=6379,db=0)
        image_code = redis_cli.get('img_{}'.format(uuid))
        if image_code:
            if image_code.decode().lower() != code.lower():
                return Response({'msg':'验证码输入错误'})
            else:
                return Response({'code':200})
        else:
            return Response({'msg':'验证码错误'})

# 注册
class UserRegister(APIView):
    def post(self,request):
        user_name = request.data.get('userName')
        pwd = request.data.get('pwd')
        mobile = request.data.get('mobile')
        agree = request.data.get('agree')
        if not agree:
            return Response({'msg':'请勾选协议'})
        Users.objects.create_user(username=user_name,password=pwd,mobile=mobile)
        return Response({'msg':'注册成功','code':201})

# 登录
'''
class Login(APIView):
    def post(self,request):
        user_name = request.data.get('user')
        pwd = request.data.get('pwd')
        try:
            user = Users.objects.get(Q(username = user_name) | Q(mobile=user_name))
        except Users.DoesNotExist as e:
            return Response({'msg':'此用户不存在，请先注册','code':400})
        is_correct = check_password(pwd,user.password)
        if is_correct:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            resp = Response({"msg":'登录成功','code':200,'user':{'userName':user.username},'token':token})
            resp.set_cookie('token',token)
            return resp
        else:
            return Response({'msg':'用户名密码错误','code':400})
'''
# 登录
class Login(APIView):
    def post(self,request):
        username = request.data.get("user")
        pwd = request.data.get("pwd")
        try:
            # 完成手机号也可以登录
            rule = "^1[3-9][0-9]{9}$"
            if re.findall(rule,username):
                # 根据手机号查询用户信息
                user_info = Users.objects.get(mobile=username)
            else:
                user_info = Users.objects.get(username=username)
            # 对此用户输入的密码和数据库的密码是否一致
            check_rs = check_password(pwd,user_info.password)
            if not check_rs:
                return Response({"msg":"密码错误","code":400})
            payload = {"id":user_info.id,"username":user_info.username,"time":int(time.time()) + 84600}
            token = jwt.encode(payload,settings.SECRET_KEY,algorithm="HS256")
            return Response({"msg":"登录成功","code":200,"user":{"userName":user_info.username},"token":token})
        except Exception as e:
            return Response({"code":400,"msg":"登录失败"})

# 退出登录
class Logout(APIView):
    def post(self,request):
        return Response({'msg':'退出成功','code':200})

# 用户中心
from goods.views import check_user
class UserInfo(APIView):
    # 获取用户信息
    @check_user
    def get(self,request,payload):
        user_id = payload['id']  # 用户id
        try:
            user_info = Users.objects.get(id=user_id)  # 查询当前用户的所有信息
            user_addr_all = user_info.addr_set.all()  # 获取所有地址
            addr_list = []
            for addr in user_addr_all:
                addr_list.append({
                    'id': addr.id,
                    'receiver': addr.receiver,
                    'receiver_mobile': addr.receiver_mobile,
                    'receiver_addr': addr.receiver_addr,
                    'is_default': addr.is_default,
                })
            return Response({'code':200,'msg':'用户信息获取成功',
                             'userInfo':{
                                 'username':user_info.username,
                                 'phone':user_info.mobile,
                                 'addrs':addr_list,
                             }})
        except:
            return Response({'code':400,'msg':'用户不存在'})

    # 修改用户地址
    @check_user
    def put(self,request,payload):
        user_id = payload['id']  # 用户id
        # 前端获取
        mobile = request.data.get('phone')
        addrs = request.data.get('addrs')
        user_info = Users.objects.filter(id = user_id).first()
        if not user_info:
            return Response({'code':400,'msg':'用户不存在'})
        # 修改手机号
        rule = r'1[0-9]{10}'  # 手机号验证
        match_rs = re.findall(rule,mobile)
        if not match_rs:
            return Response({'code':400,'mag':'手机号验证失败'})
        user_info.mobile = mobile
        user_info.save()  # 提交修改到数据库
        # 修改地址
        for i in addrs:
            # 检测当前遍历的地址是否和数据库中保存的地址一致
            temp_addr = Addr.objects.filter(id=i['id'],user_id=user_id).first()
            if not temp_addr:
                continue  # 跳出循环

            # 判断收获人是否发生变化
            if temp_addr.receiver != i['receiver']:  # 用户名字
                temp_addr.receiver = i['receiver']

            # 判断电话是否发生变化
            if temp_addr.receiver_mobile != i['receiver_mobile']:
                temp_addr.receiver_mobile = i['receiver_mobile']

            # 判断收获地址
            if temp_addr.receiver_addr != i['receiver_addr']:
                temp_addr.receiver_addr = i['receiver_addr']

            # 判断是否默认发生变化
            if temp_addr.is_default != i['is_default']:
                if i['is_default']:
                    Addr.objects.filter(is_default=True,user_id=user_id).update(is_default=False)
                    temp_addr.is_default = True
                else:
                    temp_addr.is_default = False
            # 提交数据库
            temp_addr.save()
        return Response({'code':200,'msg':'修改成功'})

# 地址
class UserAddr(APIView):
    @check_user
    def get(self,request,payload):
        user_id = payload['id']
        user_info = Users.objects.filter(id=user_id).first()  # 获取当前用户
        if not user_info:
            return Response({'code':400,'msg':'用户不存在'})
        # 说明用户存在
        addr_all = user_info.addr_set.all()
        addr_list = []
        for addr in addr_all:
            temp={
                'id':addr.id,
                'receiver':addr.receiver,
                'receiver_mobile':addr.receiver_mobile,
                'receiver_addr': addr.receiver_addr,
                'is_default':addr.is_default
            }
            addr_list.append(temp)
        return Response({'code':200,'msg':'地址获取成功','addrList':addr_list})

    @check_user
    def post(self,request,payload):
        user_id = payload['id']
        receiver = request.data.get('receiver')
        receiver_addr = request.data.get('receiver_addr')
        receiver_mobile = request.data.get('receiver_mobile')
        is_default = request.data.get('is_default')
        save_addr = Addr.objects.create(
            receiver = receiver,
            receiver_addr = receiver_addr,
            receiver_mobile = receiver_mobile,
            is_default = is_default,
            user_id = user_id,
        )
        return Response({'code':200,'msg':'新增地址成功',
                         'addr':{
                             'id': save_addr.id,
                             'receiver': save_addr.receiver,
                             'receiver_mobile': save_addr.receiver_mobile,
                             'receiver_addr': save_addr.receiver_addr,
                             'is_default': save_addr.is_default,
                         }})

    @check_user
    def delete(self,request,payload):
        user_id = payload['id']
        addr_id = request.data.get('addr_id')
        print(user_id,addr_id)
        addr_info = Addr.objects.filter(id=addr_id,user_id=user_id).first()
        print('11111',addr_info)
        if not addr_info:
            return Response({'code':400,'msg':'地址不存在'})
        else:
            addr_info.delete()

            return Response({'code':200,'msg':'地址删除成功'})

# 用户密码
class UserPwd(APIView):
    @check_user
    def put(self,request,payload):
        user_id = payload['id']
        # 原始密码
        old_password = request.data.get('originPw')
        # 新密码
        password = request.data.get('newPw')
        password_re = request.data.get('conpwd')

        user_info = Users.objects.filter(id = user_id).frist()
        if not user_info:
            return Response({'code':400,'msg':'用户不存在'})
        # 验证密码 加密用的是django自带的方法 check_password
        check = check_password(old_password,user_info.password)
        if not check:
            return Response({'code':400,'msg':'原始密码错误'})
        user_info.set_password(password)
        user_info.save()
        return Response({'code':200,'msg':'密码修改成功'})





